package com.hmall.common.config;

import com.hmall.common.utils.UserContext;
import org.aopalliance.intercept.MethodInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
@ConditionalOnClass(RabbitTemplate.class)
public class MqConfig {
    private static final Logger log = LoggerFactory.getLogger(MqConfig.class);

    @Bean
    public MessageConverter messageConverter() {
        // 定义消息转换器
        Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
        // 配置自动创建消息id，用于识别不同消息，也可以在业务中基于ID判断是否是重复消息
        jackson2JsonMessageConverter.setCreateMessageIds(true);
        return jackson2JsonMessageConverter;
    }


    // 配置 RabbitTemplate
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(messageConverter); // 设置消息转换器

        // 添加消息后处理器，自动添加 userId 到消息头
        rabbitTemplate.setBeforePublishPostProcessors(message -> {
            Long userId = UserContext.getUser();
            if (userId != null) {
                message.getMessageProperties().setHeader("user-info", userId);
            }
            return message;
        });

        return rabbitTemplate;
    }

    // 配置 MethodInterceptor（用于拦截消息并设置上下文）
    @Bean
    public MethodInterceptor userContextInterceptor() {
        return invocation -> {
            Object[] args = invocation.getArguments();

            if (args.length > 0) {
                for (Object arg : args) {
                    if (arg instanceof Message) {
                        Message message = (Message) arg;
                        Long userId = message.getMessageProperties().getHeader("user-info");

                        if (userId != null) {
                            UserContext.setUser(userId);
                        }
                        break;
                    }
                }
            }

            try {
                return invocation.proceed();
            } finally {
                UserContext.removeUser();
            }
        };
    }


    // 配置 SimpleRabbitListenerContainerFactory
    @Bean
    public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(
            ConnectionFactory connectionFactory,
            MessageConverter messageConverter,
            MethodInterceptor userContextInterceptor) {

        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(messageConverter);

        // 添加 MethodInterceptor
        factory.setAdviceChain(userContextInterceptor);

        return factory;
    }
}
